//
//  WCLRecordEncoder.m
//  WCL
//
//  Created by WangZhenyu on 2020/12/4.
//

#import "WCLRecordEncoder.h"
#import "CustomAlertView.h"
#import "UIViewControllerCJHelper.h"
#import "CustomRecordModel.h"

@interface WCLRecordEncoder () {
    BOOL isShowAlert;
    BOOL audioZhanYong;
}

@property (nonatomic, strong) AVAssetWriter *writer;//媒体写入对象
@property (nonatomic, strong) AVAssetWriterInput *audioInput;//音频写入
@property (nonatomic, strong) NSString *path;//写入路径
@property (nonatomic, strong) CustomRecordModel *recordModel;

@end

@implementation WCLRecordEncoder

- (void)dealloc {
    _writer = nil;
    _audioInput = nil;
    _path = nil;
}

+ (WCLRecordEncoder*)encoderForAudioPath:(NSString*)path model:(CustomRecordModel *)model{
    WCLRecordEncoder* enc = [WCLRecordEncoder alloc];
    return [enc initAudioPath:path model:model];
}

//初始化音频方法
- (instancetype)initAudioPath:(NSString*)path model:(CustomRecordModel *)model {
    self = [super init];
    if (self) {
        self.path = path;
    }
    self.recordModel = model;
    //先把路径下的文件给删除掉，保证录制的文件是最新的
    [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
    NSURL* url = [NSURL fileURLWithPath:path];
    //初始化写入媒体类型为MP4类型
    _writer = [AVAssetWriter assetWriterWithURL:url fileType:model.fileType error:nil];
    //使其更适合在网络上播放
    _writer.shouldOptimizeForNetworkUse = YES;
    //初始化音频输出
    [self initAudioInputModel:model];
    return self;
}

//初始化音频输入
- (void)initAudioInputModel:(CustomRecordModel *)model {
    NSInteger channels = model.channels;
    if (channels > 2) {
        channels = 2;
        audioZhanYong = YES;
    }
    if ([model.name isEqualToString:@"mp3"]) {//mp3需要将通道设置为2，否则转换会出现变声情况
        channels = 2;
    }
    NSMutableDictionary* settings = [NSMutableDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithFloat:model.rate], AVSampleRateKey,
    [NSNumber numberWithInteger:channels], AVNumberOfChannelsKey,
    [NSNumber numberWithInteger:model.formatIdKey],AVFormatIDKey,
    nil];
    if (model.formatIdKey == kAudioFormatLinearPCM) {
        [settings setObject:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
        [settings setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
        [settings setObject:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
        [settings setObject:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsNonInterleaved];
    } else {
        [settings setObject:[NSNumber numberWithInteger:model.quality] forKey:AVEncoderAudioQualityKey];
    }
    
    //初始化音频写入类
    _audioInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:settings];
    //表明输入是否应该调整其处理为实时数据源的数据
    _audioInput.expectsMediaDataInRealTime = YES;
    //将音频输入源加入
    [_writer addInput:_audioInput];
    
}

//完成视频录制时调用
- (void)finishWithCompletionHandler:(void (^)(void))handler {
    NSLog(@"完成写入");
    if (self.isCanWrite) {
        [_writer finishWritingWithCompletionHandler: handler];
    }
    isShowAlert = NO;
}


//通过这个方法写入数据
- (BOOL)encodeFrame:(CMSampleBufferRef) sampleBuffer {
    //数据是否准备写入
    
    if (CMSampleBufferDataIsReady(sampleBuffer)) {
        //写入状态为未知,保证视频先写入
//        if (_writer.status == AVAssetWriterStatusUnknown && isVideo) {
//            //获取开始写入的CMTime
//            CMTime startTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
//            //开始写入
//            [_writer startWriting];
//            [_writer startSessionAtSourceTime:startTime];
//        }
        if (_writer.status == AVAssetWriterStatusUnknown) {
            //获取开始写入的CMTime
            CMTime startTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
            //开始写入
            [_writer startWriting];
            [_writer startSessionAtSourceTime:startTime];
            self.isCanWrite = YES;
        }
        //写入失败
        if (_writer.status == AVAssetWriterStatusFailed) {
            NSLog(@"writer error %@", _writer.error.localizedDescription);
            if (!isShowAlert && audioZhanYong) {
                isShowAlert = YES;
                dispatch_async(dispatch_get_main_queue(), ^{
                    CustomAlertView *alertView = [[CustomAlertView alloc] initItem:@"当前麦克风已被其他应用占用，请关闭其他应用的音频播放或录音功能，否则将会影响答题" withButtons:[NSArray arrayWithObjects:@"退出", nil]];
                    alertView.SureHandle = ^{
                        [[UIViewControllerCJHelper findCurrentShowingViewController].navigationController popViewControllerAnimated:YES];
                    };
                    [alertView backgroundClickDisable];
                    [alertView show];
                });
            }
            
            
            return NO;
        }
        //音频输入是否准备接受更多的媒体数据
        if (_audioInput.readyForMoreMediaData) {
            //拼接数据
            [_audioInput appendSampleBuffer:sampleBuffer];
            return YES;
        }
    }
    return NO;
}

@end
